<template>
  <div class="flowchart-editor">
    <n-card>
      <template #header>
        <div class="editor-header">
          <h3>流程图编辑器</h3>
          <n-space>
            <n-button @click="addNode('task')">添加任务节点</n-button>
            <n-button @click="addNode('decision')">添加决策节点</n-button>
            <n-button @click="addNode('start')">添加开始节点</n-button>
            <n-button @click="addNode('end')">添加结束节点</n-button>
            <n-button type="error" @click="deleteSelected" :disabled="!selectedItem">
              删除选中
            </n-button>
          </n-space>
        </div>
      </template>

      <div class="editor-container">
        <!-- 工具栏 -->
        <div class="toolbar">
          <n-space vertical>
            <n-tooltip trigger="hover" placement="right">
              <template #trigger>
                <n-button 
                  :type="mode === 'select' ? 'primary' : 'default'"
                  @click="mode = 'select'"
                  circle
                >
                  <n-icon>
                    <svg viewBox="0 0 24 24"><path d="M3,3H5V5H3V3M7,3H9V5H7V3M11,3H13V5H11V3M15,3H17V5H15V3M19,3H21V5H19V3M3,7H5V9H3V7M7,7H21V9H7V7M3,11H5V13H3V11M7,11H21V13H7V11M3,15H5V17H3V15M7,15H21V17H7V15M3,19H5V21H3V19M7,19H9V21H7V19M11,19H13V21H11V19M15,19H17V21H15V19M19,19H21V21H19V19" /></svg>
                  </n-icon>
                </n-button>
              </template>
              选择工具
            </n-tooltip>
            
            <n-tooltip trigger="hover" placement="right">
              <template #trigger>
                <n-button 
                  :type="mode === 'connect' ? 'primary' : 'default'"
                  @click="mode = 'connect'"
                  circle
                >
                  <n-icon>
                    <svg viewBox="0 0 24 24"><path d="M9,11H15V8L19,12L15,16V13H9V16L5,12L9,8V11M2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12Z" /></svg>
                  </n-icon>
                </n-button>
              </template>
              连接工具
            </n-tooltip>
          </n-space>
        </div>

        <!-- 画布 -->
        <div class="canvas" ref="canvasRef" @click="handleCanvasClick">
          <!-- SVG 连线 -->
          <svg class="edges-layer">
            <defs>
              <marker
                id="arrow"
                markerWidth="10"
                markerHeight="10"
                refX="9"
                refY="3"
                orient="auto"
                markerUnits="strokeWidth"
              >
                <polygon points="0 0, 10 3, 0 6" fill="#666" />
              </marker>
            </defs>
            
            <g v-for="edge in edges" :key="edge.id">
              <path
                :d="getEdgePath(edge)"
                fill="none"
                stroke="#666"
                stroke-width="2"
                marker-end="url(#arrow)"
                :class="{ 'selected': selectedItem?.type === 'edge' && selectedItem.id === edge.id }"
                @click.stop="selectEdge(edge)"
              />
            </g>
          </svg>

          <!-- 节点 -->
          <div
            v-for="node in nodes"
            :key="node.id"
            class="node"
            :class="[
              `node-${node.type}`,
              { 'selected': selectedItem?.type === 'node' && selectedItem.id === node.id }
            ]"
            :style="{
              left: node.position.x + 'px',
              top: node.position.y + 'px'
            }"
            @mousedown="handleNodeMouseDown(node, $event)"
            @click.stop="selectNode(node)"
          >
            <div class="node-content">
              <input
                v-if="editingNode === node.id"
                v-model="node.label"
                @blur="editingNode = null"
                @keyup.enter="editingNode = null"
                class="node-label-input"
                autofocus
              />
              <div v-else class="node-label" @dblclick="editingNode = node.id">
                {{ node.label }}
              </div>
            </div>
            
            <!-- 连接点 -->
            <div 
              v-if="mode === 'connect'"
              class="connection-point"
              @mousedown.stop="startConnection(node)"
            />
          </div>

          <!-- 临时连线 -->
          <svg v-if="connecting" class="temp-edge-layer" :style="{ pointerEvents: 'none' }">
            <path
              :d="tempEdgePath"
              fill="none"
              stroke="#2080f0"
              stroke-width="2"
              stroke-dasharray="5,5"
            />
          </svg>
        </div>

        <!-- 属性面板 -->
        <div class="properties-panel" v-if="selectedItem">
          <h4>属性</h4>
          <n-form v-if="selectedItem.type === 'node'" label-placement="top">
            <n-form-item label="标签">
              <n-input v-model:value="selectedNode.label" />
            </n-form-item>
            <n-form-item label="类型">
              <n-select 
                v-model:value="selectedNode.type"
                :options="nodeTypeOptions"
              />
            </n-form-item>
          </n-form>
          
          <n-form v-else-if="selectedItem.type === 'edge'" label-placement="top">
            <n-form-item label="标签">
              <n-input v-model:value="selectedEdge.label" placeholder="可选" />
            </n-form-item>
          </n-form>
        </div>
      </div>
    </n-card>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, reactive } from 'vue'
import { 
  NCard, NSpace, NButton, NIcon, NTooltip, NForm, NFormItem, NInput, NSelect 
} from 'naive-ui'
import type { FlowchartNode, FlowchartEdge } from '@/api/taskFlowchart'
import { v4 as uuidv4 } from 'uuid'

// Props 和 Emits
interface Props {
  initialNodes?: FlowchartNode[]
  initialEdges?: FlowchartEdge[]
}

const props = defineProps<Props>()

const emit = defineEmits<{
  'update:nodes': [nodes: FlowchartNode[]]
  'update:edges': [edges: FlowchartEdge[]]
}>()

// 状态
const mode = ref<'select' | 'connect'>('select')
const nodes = ref<FlowchartNode[]>(props.initialNodes || [])
const edges = ref<FlowchartEdge[]>(props.initialEdges || [])
const selectedItem = ref<{ type: 'node' | 'edge'; id: string } | null>(null)
const editingNode = ref<string | null>(null)
const canvasRef = ref<HTMLElement>()

// 拖拽相关
const dragging = ref(false)
const dragNode = ref<FlowchartNode | null>(null)
const dragOffset = ref({ x: 0, y: 0 })

// 连线相关
const connecting = ref(false)
const connectionStart = ref<FlowchartNode | null>(null)
const mousePosition = ref({ x: 0, y: 0 })

// 节点类型选项
const nodeTypeOptions = [
  { label: '任务', value: 'task' },
  { label: '决策', value: 'decision' },
  { label: '开始', value: 'start' },
  { label: '结束', value: 'end' }
]

// 计算属性
const selectedNode = computed(() => {
  if (selectedItem.value?.type === 'node') {
    return nodes.value.find(n => n.id === selectedItem.value!.id)
  }
  return null
})

const selectedEdge = computed(() => {
  if (selectedItem.value?.type === 'edge') {
    return edges.value.find(e => e.id === selectedItem.value!.id)
  }
  return null
})

const tempEdgePath = computed(() => {
  if (!connecting.value || !connectionStart.value) return ''
  
  const start = connectionStart.value
  const sx = start.position.x + 75
  const sy = start.position.y + 30
  const ex = mousePosition.value.x
  const ey = mousePosition.value.y
  
  return `M ${sx} ${sy} L ${ex} ${ey}`
})

// 添加节点
function addNode(type: string) {
  const node: FlowchartNode = {
    id: uuidv4(),
    type,
    label: `新${type === 'task' ? '任务' : type === 'decision' ? '决策' : type === 'start' ? '开始' : '结束'}`,
    position: { x: 100, y: 100 },
    data: {}
  }
  nodes.value.push(node)
  emitUpdate()
}

// 删除选中项
function deleteSelected() {
  if (!selectedItem.value) return
  
  if (selectedItem.value.type === 'node') {
    // 删除节点及相关边
    nodes.value = nodes.value.filter(n => n.id !== selectedItem.value!.id)
    edges.value = edges.value.filter(e => 
      e.source !== selectedItem.value!.id && e.target !== selectedItem.value!.id
    )
  } else {
    // 删除边
    edges.value = edges.value.filter(e => e.id !== selectedItem.value!.id)
  }
  
  selectedItem.value = null
  emitUpdate()
}

// 选择节点
function selectNode(node: FlowchartNode) {
  selectedItem.value = { type: 'node', id: node.id }
}

// 选择边
function selectEdge(edge: FlowchartEdge) {
  selectedItem.value = { type: 'edge', id: edge.id }
}

// 处理节点鼠标按下
function handleNodeMouseDown(node: FlowchartNode, event: MouseEvent) {
  if (mode.value === 'select') {
    startDragging(node, event)
  }
}

// 开始拖拽
function startDragging(node: FlowchartNode, event: MouseEvent) {
  dragging.value = true
  dragNode.value = node
  const rect = canvasRef.value!.getBoundingClientRect()
  dragOffset.value = {
    x: event.clientX - rect.left - node.position.x,
    y: event.clientY - rect.top - node.position.y
  }
  
  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', handleMouseUp)
}

// 处理鼠标移动
function handleMouseMove(event: MouseEvent) {
  const rect = canvasRef.value!.getBoundingClientRect()
  mousePosition.value = {
    x: event.clientX - rect.left,
    y: event.clientY - rect.top
  }
  
  if (dragging.value && dragNode.value) {
    dragNode.value.position.x = mousePosition.value.x - dragOffset.value.x
    dragNode.value.position.y = mousePosition.value.y - dragOffset.value.y
  }
}

// 处理鼠标抬起
function handleMouseUp() {
  if (dragging.value) {
    dragging.value = false
    dragNode.value = null
    emitUpdate()
  }
  
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', handleMouseUp)
}

// 开始连接
function startConnection(node: FlowchartNode) {
  connecting.value = true
  connectionStart.value = node
  
  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', endConnection)
}

// 结束连接
function endConnection() {
  connecting.value = false
  connectionStart.value = null
  
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', endConnection)
}

// 处理画布点击
function handleCanvasClick(event: MouseEvent) {
  if (mode.value === 'connect' && connecting.value && connectionStart.value) {
    // 检查是否点击到了节点
    const target = event.target as HTMLElement
    const nodeEl = target.closest('.node')
    if (nodeEl) {
      const nodeId = nodes.value.find(n => 
        nodeEl.style.left === n.position.x + 'px' && 
        nodeEl.style.top === n.position.y + 'px'
      )?.id
      
      if (nodeId && nodeId !== connectionStart.value.id) {
        // 创建新边
        const edge: FlowchartEdge = {
          id: uuidv4(),
          source: connectionStart.value.id,
          target: nodeId,
          type: 'default'
        }
        edges.value.push(edge)
        emitUpdate()
      }
    }
    
    endConnection()
  } else if (!event.target || !(event.target as HTMLElement).closest('.node')) {
    selectedItem.value = null
  }
}

// 获取边路径
function getEdgePath(edge: FlowchartEdge): string {
  const source = nodes.value.find(n => n.id === edge.source)
  const target = nodes.value.find(n => n.id === edge.target)
  
  if (!source || !target) return ''
  
  const sx = source.position.x + 75
  const sy = source.position.y + 30
  const tx = target.position.x + 75
  const ty = target.position.y + 30
  
  // 贝塞尔曲线
  const mx = (sx + tx) / 2
  const my = (sy + ty) / 2
  const cx = mx
  const cy = my - Math.abs(tx - sx) * 0.2
  
  return `M ${sx} ${sy} Q ${cx} ${cy} ${tx} ${ty}`
}

// 发送更新事件
function emitUpdate() {
  emit('update:nodes', nodes.value)
  emit('update:edges', edges.value)
}
</script>

<style scoped>
.flowchart-editor {
  height: 100%;
}

.editor-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.editor-container {
  display: flex;
  gap: 20px;
  height: 600px;
}

.toolbar {
  width: 60px;
  background: #f5f5f5;
  padding: 10px;
  border-radius: 8px;
}

.canvas {
  flex: 1;
  position: relative;
  background: #fafafa;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  overflow: hidden;
}

.edges-layer,
.temp-edge-layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.edges-layer path {
  cursor: pointer;
  transition: stroke 0.3s;
}

.edges-layer path:hover {
  stroke: #2080f0;
}

.edges-layer path.selected {
  stroke: #18a058;
  stroke-width: 3;
}

.node {
  position: absolute;
  min-width: 150px;
  min-height: 60px;
  border: 2px solid #666;
  background: white;
  border-radius: 8px;
  padding: 10px;
  cursor: move;
  user-select: none;
  transition: all 0.3s;
}

.node:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.node.selected {
  border-color: #18a058;
  box-shadow: 0 0 0 3px rgba(24, 160, 88, 0.2);
}

.node-task {
  border-color: #2080f0;
  background: #f0f8ff;
}

.node-decision {
  border-color: #f0a020;
  background: #fffaf0;
}

.node-start {
  border-color: #18a058;
  background: #f0f9ff;
  border-radius: 50%;
}

.node-end {
  border-color: #d03050;
  background: #fff0f0;
  border-radius: 50%;
}

.node-content {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.node-label {
  text-align: center;
  font-size: 14px;
}

.node-label-input {
  width: 100%;
  border: 1px solid #2080f0;
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 14px;
  outline: none;
}

.connection-point {
  position: absolute;
  bottom: -5px;
  left: 50%;
  transform: translateX(-50%);
  width: 10px;
  height: 10px;
  background: #2080f0;
  border-radius: 50%;
  cursor: crosshair;
}

.properties-panel {
  width: 250px;
  background: white;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 20px;
}

.properties-panel h4 {
  margin-top: 0;
  margin-bottom: 16px;
}
</style>